﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;

namespace Eniux.Windows.ThreeDEngine.Geometry
{
    /// <summary>
    /// 描述一个平面
    /// </summary>
    public class Plane3D
    {
        #region 常量、字段

        /// <summary>
        /// 法线
        /// </summary>
        internal Vector3D normal;

        /// <summary>
        /// 位置
        /// </summary>
        internal Point3D position;

        #endregion

        #region 构造、析构

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Plane3D()
        {
        }

        /// <summary>
        /// 有参构造函数
        /// </summary>
        /// <param name="p">位置</param>
        /// <param name="n">法线</param>
        public Plane3D(Point3D p, Vector3D normal)
        {
            Position = p;
            Normal = normal;
        }

        #endregion

        #region 公共属性

        /// <summary>
        /// 获取或设置法线
        /// </summary>
        public Vector3D Normal
        {
            get{return normal;}
            set{normal = value;} 
        }

        /// <summary>
        /// 获取或设置位置
        /// </summary>
        public Point3D Position
        {
            get{return position;}
            set{ position = value;}
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 查找空间中线面的交集
        /// </summary>
        /// <param name="la">线上的一点</param>
        /// <param name="lb">线上的另一点</param>
        /// <returns></returns>
        public Point3D? LineIntersection(Point3D la, Point3D lb)
        {
            // http://en.wikipedia.org/wiki/Line-plane_intersection
            var l = lb - la;
            double a = Vector3D.DotProduct(position - la, normal);
            double b = Vector3D.DotProduct(l, normal);
            if (a == 0 && b == 0)
            {
                return null;
            }

            if (b == 0)
            {
                return null;
            }

            return la + (a / b) * l;
        }

        #endregion

        // public void SetYZ(double x, int dir)
        // {
        // Position = new Point3D(x, 0, Height / 2);
        // Normal = new Vector3D(dir, 0, 0);
        // Up = new Vector3D(0, 0, 1);
        // }

        // public void SetXY(double z, int dir)
        // {
        // Position = new Point3D(0, 0, z);
        // Normal = new Vector3D(0, 0, dir);
        // Up = new Vector3D(1, 0, 0);
        // }

        // public void SetXZ(double y, int dir)
        // {
        // Position = new Point3D(0, y, 0);
        // Normal = new Vector3D(0, dir, 0);
        // Up = new Vector3D(1, 0, 0);
        // }

        // public Point3D[] GetCornerPoints()
        // {
        // var pts = new Point3D[4];
        // Vector3D right = Vector3D.CrossProduct(Normal, Up);
        // pts[0] = Position + (-right * 0.5 * Width - Up * 0.5 * Height);
        // pts[1] = Position + (right * 0.5 * Width - Up * 0.5 * Height);
        // pts[2] = Position + (right * 0.5 * Width + Up * 0.5 * Height);
        // pts[3] = Position + (-right * 0.5 * Width + Up * 0.5 * Height);
        // return pts;
        // }
    }
}
